![]() |
![]() |
|
Stößt der Programmablauf erstmals auf den Schleifenkopf, wird die Zählervariable mit dem Startwert initialisiert. Die Zählervariable wird nach jedem Durchlauf erhöht bzw. verringert – ist die optionale Schrittweite nicht mit Step angegeben, standardmäßig um +1. Eine davon abweichende Schrittweite kann sowohl positiv als auch negativ sein. In den Anweisungsblock der Schleife wird nur dann eingetreten, wenn bei positiver Schrittweite der Startwert kleiner oder gleich dem Endwert ist. Verlassen wird eine solche Schleife also genau dann, wenn die Bedingung erfüllt ist. Ist die Schrittweite negativ, gilt für das Beenden des Schleifendurchlaufs: Zähler < Endwert Ist die Abbruchbedingung erfüllt, wird das Programm mit der Anweisung fortgesetzt, die dem das Schleifenende kennzeichnenden Next folgt. Die Angabe des Zählernamens hinter der Next-Anweisung ist optional. Außerplanmäßig kann eine Schleife auch mit Exit For verlassen werden. Die Zählervariable selbst können Sie vor Eintritt in die Schleife deklarieren oder direkt hinter dem einleitenden For.
For-Next-Schleifen eignen sich unter anderem, Array-Elemente zu initialisieren. Der Zähler der Schleife wird dann dazu benutzt, um den Index eines bestimmten Elements zu adressieren. Im folgenden Codefragment wird das auf einfache Art und Weise demonstriert. Dazu wird den Elementen des Arrays das Quadrat des Indizes zugewiesen.
For-Next-Schleifen können beliebig ineinander verschachtelt werden. Im nächsten Beispiel wird gezeigt, wie eine verschachtelte Schleife dazu benutzt werden kann, um einen Baum beliebiger Größe durch Buchstaben dargestellt an der Konsole auszugeben.
Jeder Ausgabezeile setzt sich aus einer Anzahl von Leerzeichen und Buchstaben zusammen und hängt von der Größe der Darstellung ab. Für die Leerzeichen gilt: Anzahl Leerzeichen = Gesamtanzahl der Zeilen – aktuelle Zeilennummer Die auszugebenden Buchstaben folgen der Beziehung: Anzahl Buchstaben = aktuelle Zeilennummer * 2 – 1 In einer äußeren For-Next-Schleife wird jede Stufe des Baums separat behandelt. Darin eingebettet sind zwei weitere Schleifen implementiert, die jede für sich zuerst vollständig ausgeführt wird. Dabei werden in der ersten inneren Schleife zuerst die Leerzeichen geschrieben, in der zweiten die Buchstaben.
Zähler als FließkommazahlenZähler und Schrittweite müssen nicht zwangsläufig ganzzahlig sein, Fließkommazahlen sind ebenfalls zulässig. Wie Sie aber bereits wissen, sind Fließkommazahlen systembedingt immer ungenau. Das kann bei Schleifen besonders fatale Folgen haben. Sehen Sie sich dazu das folgende Codefragment an:
Würden Sie auf den ersten Blick einen Haken vermuten? Vermutlich nicht. Erst wenn Sie das Programm laufen lassen, werden Sie feststellen, dass der letzte Zählerwert fehlt.
Die Ungenauigkeit von Fließkommazahlen bewirkt, dass der Zähler im letzten Schritt zu 1,0000001 berechnet wird, obwohl er eigentlich exakt 1 sein müsste. Der dann folgende Vergleich mit dem festgelegten Endwert bewirkt den unbeabsichtigten, vorzeitigen Ausstieg aus der Schleife um einen Schritt zu früh. Das Problem kann vermieden werden, wenn sowohl Zähler als auch Schrittweite ganzzahlig gemacht werden. Der Faktor 20 erhöht die Schrittweite auf den Standardwert +1, Start- und Endwert müssen dementsprechend angepasst werden. Zum Schluss muss das Ausgabedatum wieder durch denselben Faktor dividiert werden, um korrekt angezeigt zu werden.
Mit dieser Änderung wird die Ausgabe erwartungsgemäß mit 1.0 enden. Variablendeklaration im SchleifenblockVariablen, die in einer Prozedur deklariert werden, gelten als lokal. Ihre Sichtbarkeit und ihr Gültigkeitsbereich beschränken sich in jedem Fall auf die Prozedur selbst. Variablen, die in einer For-Next-Schleife deklariert werden, sind nicht mit lokalen Variablen gleichzusetzen: Sie sind nur innerhalb der Schleife bekannt. Daher wird die Entwicklungsumgebung einen Fehler anzeigen, wenn Sie den folgenden Code schreiben:
3.6.2 Do-Loop-Schleifen
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Kopfgesteuerte Schleifen |
| Fußgesteuerte Schleifen |
Kopfgesteuerte Schleifen garantieren nicht, dass die Programmlogik im Schleifenkörper zumindest einmal durchlaufen wird, während das bei den fußgesteuerten grundsätzlich zumindest einmal der Fall ist.
Schauen wir uns zunächst die kopfgesteuerten Schleifen an. Visual Basic 2005 kennt zwei Varianten, die beide gleichwertig sind, jedoch unterschiedlich definierten Ausstiegsbedingungen unterliegen: Die Do Until-Schleife und die Do While-Schleife. Wenden wir uns zunächst der ersteren zu.
| Do Until <Bedingung> |
| ' Anweisungen |
| [Exit Do] |
| Loop |
Bei der Bedingung handelt es sich um einen booleschen Ausdruck, der entweder True oder False liefert. Er kann durch Vergleichsoperatoren gebildet werden und könnte schon bei der ersten Ausführung wahr sein. In diesem Fall werden die Anweisungen im Schleifenkörper überhaupt nicht ausgeführt, sondern das Programm mit der Anweisung fortgesetzt, die dem das Schleifenende kennzeichnenden Loop folgt.
Tritt das Programm in die Schleife ein, weil beim ersten Auftreffen des Programmablaufs die Bedingung False ist, werden die Anweisungen im Schleifenkörper so lange ausgeführt, bis die Bedingung True wird. Da keine automatische Änderung der Bedingung erfolgt wie bei der For-Next-Schleife durch Erhöhung des Zählers, müssen Sie die Austrittsbedingung programmieren – ansonsten tritt der klassische Fall einer Endlosschleife ein.
Außerplanmäßig kann eine Schleife jederzeit mit Exit Do verlassen werden. Danach wird das Programm mit der Anweisung fortgesetzt, die dem das Schleifenende kennzeichnenden Loop folgt.
Die zweite Variante einer kopfgesteuerten Schleife ähnelt sehr stark der ersten:
| Do While <Bedingung> |
| ' Anweisungen |
| [Exit Do] |
| Loop |
Im Gegensatz zu Do Until wird die Do While-Schleife genau dann abgebrochen, wenn die Bedingung False ist. Sie wird also ausgeführt, solange die Bedingung erfüllt wird.
Syntaktisch ähneln die fußgesteuerten Schleifen den kopfgesteuerten. Die Bedingungsprüfung erfolgt allerdings erst im Schleifenfuß, was zur Folge hat, dass der Anweisungsblock zumindest einmal ausgeführt wird. Die Syntax dieser beiden Varianten lautet:
| Do |
| 'Anweisungen |
| [Exit Do] |
| Loop Until <Bedingung> |
beziehungsweise
| Do |
| 'Anweisungen |
| [Exit Do] |
| Loop While <Bedingung> |
In Abschnitt 3.5.1 wurde bei der Vorstellung der bedingten Anweisung das Beispielprogramm Zufallszahl gezeigt, das den Benutzer dazu auffordert, eine beliebige Zahl zwischen 0 und 9 zu raten, die mit einer durch das Programm generierten Zufallszahl verglichen wurde.
Dem Programm mangelte es an der Möglichkeit, dem Benutzer mehrere Durchgänge zu erlauben. Das überarbeitete Programm soll nun genau dieses Manko beseitigen und wird dazu um eine Do-Schleife ergänzt. Da die Eingabe in jedem Fall einmal erfolgen muss, fällt die Wahl auf eine fußgesteuerte Schleife.
| ' -------------------------------------------------------------- |
| ' Beispiel: ...\Kapitel 3\Zufallszahl_Version2 |
| ' -------------------------------------------------------------- |
| '---------- N E U ---------- |
| Option Compare Text |
| Module Module1 |
| Sub Main() |
| Dim strText As String |
| Dim intWahl As Int32 |
| '------- N E U ------- |
| Dim bolNewGame As Boolean = True |
| Dim intCounter As Integer |
| Dim intSuccess As Integer |
| 'Zufallszahl auf Basis der Klasse Random |
| Dim rnd As New System.Random() |
| Dim intZufall As Int32 |
| '---------- N E U ---------- |
| Do |
| 'Zufallszahl im Bereich 0<= intZufall < 10 ermitteln |
| intZufall = rnd.Next(0, 10) |
| 'Anzahl der Spiele zählen |
| intCounter += 1 |
| strText = "Geben Sie eine Zahl zwischen 0 und 10 ein. " |
| Console.Write(strText) |
| intWahl = System.Convert.ToInt32(Console.ReadLine()) |
| If intZufall = intWahl Then |
| Console.WriteLine("Sie haben einen Volltreffer gelandet.") |
| intSuccess += 1 |
| Else |
| If intZufall < intWahl Then |
| Console.WriteLine("Ihre Zahl war zu gross.") |
| ElseIf intZufall > intWahl Then |
| Console.WriteLine("Ihre Zahl war zu klein.") |
| End If |
| Console.WriteLine("Die Lösung lautet: {0}", intZufall) |
| End If |
| '-------- N E U -------- |
| Console.Write("Wollen Sie noch einmal spielen (J/N)? ") |
| If CStr(Console.ReadLine()) = "N" Then bolNewGame = False |
| Console.WriteLine() |
| Loop While bolNewGame |
| 'Ausgabe des Gesamtergebnisses |
| Console.Write("Das Gesamtergebnis Spieler-Computer lautet: ") |
| Console.WriteLine("{0}:{1}", intSuccess, intCounter – intSuccess) |
| Console.ReadLine() |
| End Sub |
| End Module |
Die Wahl ist auf eine fußgesteuerte Do While-Schleife gefallen, es hätte sich aber auch ebenso gut um eine kopfgesteuerte handeln können, da die Prüfbedingung, die durch die boolesche Variable bolNewGame beschrieben wird, beim Schleifeneintritt auf jeden Fall wahr ist. Gleichermaßen könnte anstelle der Do While-Schleife auch eine Do Until-Schleife eingesetzt werden.
Ob der Schleifenblock wiederholt durchlaufen wird, bestimmt der Anwender zur Laufzeit. Möchte er das Spiel beenden, gibt er nach einer entsprechenden Aufforderung »N« bzw. »n« zum Abbruch ein. Damit bei dem Vergleich die Groß-/Kleinschreibung unberücksichtigt bleibt, ist außerhalb des Moduls der Schalter Option Compare Text gesetzt.
Wird das Spiel beendet, erfolgt zum Abschluss noch die Ausgabe des Gesamtspielstands – obwohl rein statisch gesehen der Anwender bei mehreren Schleifendurchläufen keine faire Chance hat, gegen den Rechner zu gewinnen.
Ein Überbleibsel aus den längst vergangenen Zeiten des ursprünglichen Basic/Visual Basic ist ein weiteres Schleifenkonstrukt, das im Grunde genommen völlig überflüssig ist, da es nur eine Alternative zu Do . Loop darstellt und weitergehende Möglichkeiten bietet: die einfache While-Schleife.
| While <Bedingung> |
| ' Anweisungen |
| End While |
| Schleifenkonstrukte werden in zwei Gruppen klassifiziert: bestimmte und unbestimmte Schleifen. Dabei ist der Übergang von der einen zu der anderen Gruppe nicht klar umrissen. |
| Eine For-Next-Schleife, die der Gruppe der bestimmten Schleifen zuzuordnen ist, wird meist dann eingesetzt, wenn die Anzahl der Schleifendurchläufe bei Eintritt in die Schleife bekannt ist. |
| Die For-Next-Schleife wird von einem Start- bis zu einem einschließlichen Endwert durchlaufen. Der Zähler wird standardmäßig um +1 erhöht, kann aber durch die optionale Angabe von Step den speziellen Bedürfnissen angepasst werden. |
| Do-Loop-Schleifen sind unbestimmte Schleifen. Es werden kopf- und fußgesteuerte Schleifen unterschieden. Der Anweisungsblock fußgesteuerter Schleifen wird in jedem Fall mindestens einmal durchlaufen. |
| Der Eintritt bzw. der Austritt aus einer Do-Loop-Schleife wird durch eine Bedingung gesteuert, die einen booleschen Wert repräsentiert. |
| Do Until-Schleifen werden abgeschlossen, sobald die Bedingung True ist, Do While-Schleifen genau dann, wenn die Bedingung False wird. |
| Die Bedingung muss innerhalb der Schleife geändert werden, um ein Beenden der Schleife sicherzustellen. Andernfalls wird der Anweisungsblock endlos durchlaufen. |
| Eine fünfte Variante der unbestimmten Schleifen ist While ... End While, die dasselbe Verhalten zeigt wie eine kopfgesteuerte Do While-Schleife. |
| << zurück |
|
||||||||||||||
|
||||||||||||||
|
||||||||||||||
|
||||||||||||||
Copyright © Galileo Press 2007
Für Ihren privaten Gebrauch dürfen Sie die Online-Version natürlich ausdrucken.
Ansonsten unterliegt das <openbook> denselben Bestimmungen, wie die
gebundene Ausgabe: Das Werk einschließlich aller seiner Teile ist urheberrechtlich
geschützt. Alle Rechte vorbehalten einschließlich der Vervielfältigung, Übersetzung,
Mikroverfilmung sowie Einspeicherung und Verarbeitung in elektronischen Systemen.